package route

import (
	"fmt"
	"gitee.com/gitee-go/core"
	"gitee.com/gitee-go/core/common"
	"gitee.com/gitee-go/core/model/pipeline"
	"gitee.com/gitee-go/core/models"
	"gitee.com/gitee-go/server/comm"
	"gitee.com/gitee-go/server/engine"
	"gitee.com/gitee-go/server/service"
	"gitee.com/gitee-go/utils"
	"github.com/gin-gonic/gin"
	"gopkg.in/yaml.v2"
	"strings"
)

type PluginController struct {
}

func (PluginController) GetPath() string {
	return "/api/plugin"
}
func (c *PluginController) Routes(g gin.IRoutes) {
	g.Use(service.MidUserCheck)
	g.POST("/plugins", utils.GinReqParseJson(c.plugins))
	g.POST("/plugin", utils.GinReqParseJson(c.plugin))
}

func (PluginController) plugins(c *gin.Context) {
	var ls []*models.TPlugin
	err := comm.DBMain.GetDB().Where("deleted != 1").Find(&ls)
	if err != nil {
		core.NewUIRes(common.UICodeErrs).
			SetMsgObjs(err).
			ResJson(c)
		return
	}
	runners := engine.Mgr().GetClientEgn().Runners()
	var res []string
	for _, v := range ls {
		res = append(res, fmt.Sprintf("%s@%s", v.Types, v.Name))
	}
	m := map[string]string{}
	for _, r := range runners {
		for _, s := range r.Plugin {
			if _, ok := m[s]; !ok && s != "" {
				m[s] = s
			}
		}
	}
	for _, v1 := range m {
		res = append(res, v1)
	}
	core.NewUIResOk(res).ResJson(c)
}

func (PluginController) plugin(c *gin.Context, m *utils.Map) {
	name := m.GetString("name")
	if name == "" {
		core.NewUIRes(common.UICodeErrParam).
			ResJson(c)
		return
	}
	pm := map[string]*models.Parameter{
		"commands": &models.Parameter{
			Type:        "shell",
			Rule:        []string{"bash", "sh"},
			Description: "自定义构建脚本",
			DisplayName: "构建命令",
			Required:    true,
		},
	}
	mp := map[string]*models.Plugin{
		"build@ant": &models.Plugin{
			Name:        "ant",
			Description: "ant",
			DisplayName: "ant",
			Type:        "build",
			Parameters:  pm,
		},
		"build@golang": &models.Plugin{
			Name:        "golang",
			Description: "golang",
			DisplayName: "golang",
			Type:        "build",
			Parameters:  pm,
		},
		"build@nodejs": &models.Plugin{
			Name:        "nodejs",
			Description: "nodejs",
			DisplayName: "nodejs",
			Type:        "build",
			Parameters:  pm,
		},
		"build@php": &models.Plugin{
			Name:        "php",
			Description: "php",
			DisplayName: "php",
			Type:        "build",
			Parameters:  pm,
		},
		"build@python": &models.Plugin{
			Name:        "python",
			Description: "python",
			DisplayName: "python",
			Type:        "build",
			Parameters:  pm,
		},
		"build@maven": &models.Plugin{
			Name:        "maven",
			Description: "maven",
			DisplayName: "maven",
			Type:        "build",
			Parameters:  pm,
		},
		"shell@bash": &models.Plugin{
			Name:        "bash",
			Description: "bash",
			DisplayName: "bash",
			Type:        "shell",
			Parameters:  pm,
		},
		"shell@sh": &models.Plugin{
			Name:        "sh",
			Description: "sh",
			DisplayName: "sh",
			Type:        "shell",
			Parameters:  pm,
		},
	}
	if v, ok := mp[name]; ok {
		core.NewUIResOk(v.Parameters).ResJson(c)
		return
	}
	if !strings.Contains(name, "@") {
		core.NewUIRes(common.UICodeErrParam).
			ResJson(c)
		return
	}
	split := strings.Split(name, "@")
	if len(split) != 2 {
		core.NewUIRes(common.UICodeErrParam).
			ResJson(c)
		return
	}
	tp := &pipeline.TPlugin{}
	get, _ := comm.DBMain.GetDB().Where("types=? and name = ?", split[0], split[1]).Get(tp)
	if !get {
		core.NewUIRes(common.UICodeErrNotFound).
			ResJson(c)
		return
	}
	plugin := &models.Plugin{}
	err := yaml.Unmarshal([]byte(tp.Content), plugin)
	if err != nil {
		core.NewUIRes(common.UICodeErrs).
			SetMsgObjs(err).
			ResJson(c)
		return
	}
	core.NewUIResOk(plugin.Parameters).ResJson(c)
}
